// $Id: param_value_list.c,v 1.1.1.1 2012/02/17 03:45:26 hzheng Exp $

#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "log.h"
#include "obj.h"

#include "data.h"
#include "data_action.h"

void evcpe_param_value_list_init(struct evcpe_param_value_list *list)
{
	TAILQ_INIT(&list->head);
	list->size = 0;
}

void evcpe_param_value_list_clear(struct evcpe_param_value_list *list)
{
	struct evcpe_param_value *param;
	struct param_values *content = NULL;

	evcpe_debug(__func__, "clearing evcpe_param_value_list");

	while((param = TAILQ_FIRST(&list->head))) {
		TAILQ_REMOVE(&list->head, param, entry);
		if (param->content)
		{	
			content = (struct param_values *)param->content;

			if(content->value)	
				free(content->value);
			if(content->name)	
				free(content->name);
			free(param->content);
			param->content = NULL;
		}
		free(param);
	}
	list->size = 0;
}

int evcpe_param_value_set(struct evcpe_param_value *param,
		const char *data, unsigned len)
{
	if (!param) return EINVAL;

	evcpe_debug(__func__, "setting value: %s => %.*s",
			param->name, len, data);
	param->data = data;
	param->len = len;
	return 0;
}

unsigned int evcpe_param_value_list_size(struct evcpe_param_value_list *list)
{
	return list->size;
}

struct evcpe_param_value *evcpe_param_value_find(
		struct evcpe_param_value_list *list, const char *name)
{
	struct evcpe_param_value *value;

	//evcpe_debug(__func__, "finding name: %s", name);

	TAILQ_FOREACH(value, &list->head, entry) {
		if (!strcmp(name, value->name))
			return value;
	}
	return NULL;
}

struct evcpe_param_value *evcpe_param_value_get(
		struct evcpe_param_value_list *list, const char *name)
{
	struct evcpe_param_value *value;

	evcpe_debug(__func__, "getting para: %s", name);

	if(!(value = evcpe_param_value_find(list, name)))
		return NULL;
	
	TAILQ_REMOVE(&list->head, value, entry);
	list->size --;

	return value;
}

int evcpe_param_value_list_add_one(struct evcpe_param_value_list *list,
		struct evcpe_param_value *param)
{
	evcpe_debug(__func__, "adding parameter: %s", param->name);
	
	TAILQ_INSERT_TAIL(&list->head, param, entry);
	list->size ++;
	
	return 0;
}

int evcpe_param_value_list_add(struct evcpe_param_value_list *list,
		struct evcpe_param_value **value, const char *name, unsigned len)
{
	int rc;
	struct evcpe_param_value *param;

	if (!name || !len) return EINVAL;
	if (len >= sizeof(param->name)) return EOVERFLOW;

	//evcpe_debug(__func__, "adding parameter: %.*s", len, name);

	if (!(param = calloc(1, sizeof(struct evcpe_param_value)))) {
		evcpe_error(__func__, "failed to calloc evcpe_param_value");
		rc = ENOMEM;
		goto finally;
	}
	strncpy(param->name, name, len);
	TAILQ_INSERT_TAIL(&list->head, param, entry);
	*value = param;
	list->size ++;
	rc = 0;

finally:
	return rc;
}

void evcpe_param_value_list_remove(struct evcpe_param_value_list *list,
		struct evcpe_param_value *param)
{
	struct param_values *content = NULL;

	TAILQ_REMOVE(&list->head, param, entry);
	list->size --;
	if (param->content)
	{	
		content = (struct param_values *)param->content;
		if(content->value)	free(content->value);
		if(content->name)	free(content->name);
		free(param->content);
		param->content = NULL;
	}

	free(param);
}
